/**
 * LangChain.js 概念验证示例
 * 
 * 此文件展示如何使用LangChain.js实现AIDE项目中的AI聊天功能
 * 包括基本聊天、流式响应和工具调用
 */

// 导入LangChain.js依赖
const { ChatOpenAI } = require("@langchain/openai");
const { HumanMessage, AIMessage, SystemMessage } = require("@langchain/core/messages");
const { tool } = require("@langchain/core/tools");
const { z } = require("zod");
const { StringOutputParser } = require("@langchain/core/output_parsers");
const { RunnableSequence } = require("@langchain/core/runnables");

// 环境配置
require('dotenv').config();

// 初始化聊天模型
const chatModel = new ChatOpenAI({
  openAIApiKey: process.env.OPENAI_API_KEY,
  configuration: {
    baseURL: process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1'
  },
  modelName: process.env.OPENAI_MODEL || 'gpt-3.5-turbo',
  temperature: 0.7,
  maxTokens: 1000,
  streaming: true
});

// 定义工具 - 创建任务
const createTaskTool = tool(
  async ({ title, description, priority, dueDate, category, tags }) => {
    console.log(`创建任务: ${title}`);
    
    // 在实际实现中，这里会调用数据库操作
    const taskId = `task_${Date.now()}`;
    const result = {
      id: taskId,
      title,
      description: description || '',
      priority: priority || 'P2',
      dueDate: dueDate || null,
      category: category || 'work',
      tags: tags || [],
      status: 'todo',
      completed: false,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
    
    return JSON.stringify({
      success: true,
      data: result,
      message: `已创建任务"${title}"，优先级：${result.priority}`
    });
  },
  {
    name: "create_task",
    description: "创建新任务",
    schema: z.object({
      title: z.string().describe("任务标题"),
      description: z.string().optional().describe("任务描述"),
      priority: z.enum(["P0", "P1", "P2", "P3"]).optional().describe("任务优先级"),
      dueDate: z.string().optional().describe("截止日期"),
      category: z.string().optional().describe("任务分类"),
      tags: z.array(z.string()).optional().describe("任务标签")
    })
  }
);

// 定义工具 - 查询任务
const queryTasksTool = tool(
  async ({ filters, sortBy, limit }) => {
    console.log(`查询任务列表: ${JSON.stringify(filters || {})}`);
    
    // 在实际实现中，这里会查询数据库
    const mockTasks = [
      {
        id: "task_001",
        title: "完成项目报告",
        description: "准备下周的项目进度报告",
        priority: "P1",
        dueDate: "2023-05-15T00:00:00Z",
        category: "work",
        tags: ["报告", "项目"],
        status: "todo",
        completed: false
      },
      {
        id: "task_002",
        title: "购买生日礼物",
        description: "为妈妈买生日礼物",
        priority: "P2",
        dueDate: "2023-05-20T00:00:00Z",
        category: "personal",
        tags: ["购物", "礼物"],
        status: "todo",
        completed: false
      }
    ];
    
    return JSON.stringify({
      success: true,
      data: {
        tasks: mockTasks,
        total: mockTasks.length,
        returned: mockTasks.length
      },
      message: `找到${mockTasks.length}个任务`
    });
  },
  {
    name: "query_tasks",
    description: "查询任务列表",
    schema: z.object({
      filters: z.object({
        status: z.string().optional().describe("任务状态"),
        priority: z.string().optional().describe("任务优先级"),
        category: z.string().optional().describe("任务分类"),
        tags: z.array(z.string()).optional().describe("任务标签"),
        dueDate: z.string().optional().describe("截止日期范围")
      }).optional().describe("过滤条件"),
      sortBy: z.string().optional().describe("排序方式"),
      limit: z.number().optional().describe("返回数量限制")
    })
  }
);

// 绑定工具到模型
const modelWithTools = chatModel.bindTools([createTaskTool, queryTasksTool]);

// 系统提示词
const systemPrompt = `你是AIDE智能任务管理助手。你可以帮助用户创建、更新、查询和管理任务。

你可以使用以下功能：
- 创建新任务 (create_task)
- 查询任务列表 (query_tasks)

请根据用户需求提供帮助，如果需要操作任务，请使用相应的功能。回答要简洁明了。`;

// 示例1: 基本聊天（非流式）
async function basicChatExample() {
  console.log("\n=== 基本聊天示例 ===");
  
  const messages = [
    new SystemMessage(systemPrompt),
    new HumanMessage("你好，请介绍一下你自己")
  ];
  
  const response = await chatModel.invoke(messages);
  console.log("AI回复:", response.content);
}

// 示例2: 流式聊天
async function streamingChatExample() {
  console.log("\n=== 流式聊天示例 ===");
  
  const messages = [
    new SystemMessage(systemPrompt),
    new HumanMessage("你能帮我做什么？")
  ];
  
  const stream = await chatModel.stream(messages);
  
  console.log("AI回复: ");
  let content = "";
  for await (const chunk of stream) {
    process.stdout.write(chunk.content);
    content += chunk.content;
  }
  console.log("\n");
  
  return content;
}

// 示例3: 工具调用 - 创建任务
async function createTaskExample() {
  console.log("\n=== 工具调用示例 - 创建任务 ===");
  
  const messages = [
    new SystemMessage(systemPrompt),
    new HumanMessage("帮我创建一个明天下午3点截止的高优先级任务，标题是'完成季度报告'，分类是'工作'")
  ];
  
  const response = await modelWithTools.invoke(messages);
  console.log("AI回复:", response.content);
  
  // 打印工具调用信息
  if (response.tool_calls && response.tool_calls.length > 0) {
    console.log("\n工具调用信息:");
    console.log(JSON.stringify(response.tool_calls, null, 2));
  }
  
  return response;
}

// 示例4: 工具调用 - 查询任务
async function queryTasksExample() {
  console.log("\n=== 工具调用示例 - 查询任务 ===");
  
  const messages = [
    new SystemMessage(systemPrompt),
    new HumanMessage("查询所有工作类别的任务")
  ];
  
  const response = await modelWithTools.invoke(messages);
  console.log("AI回复:", response.content);
  
  // 打印工具调用信息
  if (response.tool_calls && response.tool_calls.length > 0) {
    console.log("\n工具调用信息:");
    console.log(JSON.stringify(response.tool_calls, null, 2));
  }
  
  return response;
}

// 示例5: 工具调用结果处理
async function toolResultsExample() {
  console.log("\n=== 工具调用结果处理示例 ===");
  
  const messages = [
    new SystemMessage(systemPrompt),
    new HumanMessage("查询所有待办任务")
  ];
  
  // 1. 获取模型响应，可能包含工具调用
  const aiMessage = await modelWithTools.invoke(messages);
  console.log("AI初始响应:", aiMessage.content);
  
  // 2. 如果有工具调用，执行工具并获取结果
  if (aiMessage.tool_calls && aiMessage.tool_calls.length > 0) {
    const toolCall = aiMessage.tool_calls[0];
    console.log("\n执行工具调用:", toolCall.name);
    
    // 在实际应用中，这里会调用真实的工具函数
    // 这里我们模拟一个工具调用结果
    const toolResult = {
      success: true,
      data: {
        tasks: [
          { id: "task_001", title: "完成项目报告", status: "todo" },
          { id: "task_002", title: "准备会议材料", status: "todo" }
        ],
        total: 2
      },
      message: "找到2个待办任务"
    };
    
    // 3. 将工具调用结果传回模型
    const updatedMessages = [
      ...messages,
      aiMessage,
      {
        tool_call_id: toolCall.id,
        role: "tool",
        name: toolCall.name,
        content: JSON.stringify(toolResult)
      }
    ];
    
    // 4. 获取最终响应
    const finalResponse = await modelWithTools.invoke(updatedMessages);
    console.log("\nAI最终响应:", finalResponse.content);
    
    return finalResponse;
  }
  
  return aiMessage;
}

// 执行示例
async function runExamples() {
  try {
    await basicChatExample();
    await streamingChatExample();
    await createTaskExample();
    await queryTasksExample();
    await toolResultsExample();
  } catch (error) {
    console.error("执行示例时出错:", error);
  }
}

// 运行所有示例
runExamples();
